package galaxy;




import java.awt.Font;
import java.util.LinkedList;
import java.util.List;

import galaxy.drawer.Context;
import galaxy.drawer.NodeActionExecutor;
import galaxy.drawer.drawable.Drawable;
import galaxy.drawer.drawable.Taivas;
import galaxy.generator.Generator;
import galaxy.generator.Node;
import galaxy.generator.NodeVisitor;
import processing.core.PApplet;
import processing.core.PFont;
import processing.core.PGraphics;
import processing.core.PImage;
import processing.core.PVector;

public class App extends PApplet {
	private List<Drawable> drawables = new LinkedList<Drawable>();

	private int scale = 2;
	
	public AbstractModel createModel()
	{
		return new GalaxyModel();
	}

	
	public void setup()
	{
		size(800, 600);
		colorMode(HSB, 255);
		noLoop();
	}
	
	public void mousePressed()
	{
		generate();
	}
	
	public void keyPressed()
	{
		generate();
	}
	
	public void generate()
	{
		drawables = new LinkedList<Drawable>();
		drawables.add(new Taivas());
		generate(createModel());
		redraw();
	}
	
	public PGraphics createGraphics()
	{
		return createGraphics(width*scale, height*scale, JAVA2D);
	}
	
	public void draw()
	{
		background(0);
		
		if (drawables.size() == 0) {
			PFont font = createFont("Arial",18);
			textFont(font);
			text("Click to take a look at the sky", height/2, width/2);
		} else {
			PGraphics g = createGraphics();
			g.beginDraw();
			g.colorMode(g.HSB, 255);
			g.smooth();
			for (Drawable d : drawables) {
				d.draw(g);
			}
			g.endDraw();
			smooth();
			PImage i = g.get();
			i.resize(width, height);
			image(i, 0, 0);
		}
	}
	
	public void generate(AbstractModel m)
	{
		getGenerator(m)
		.run(m.getRounds())
		.getState()
		.accept(getActionExecutor(m));
	}
	
	public Generator getGenerator(AbstractModel m)
	{
		return new Generator(m.getGrammar(), new Node(m.getStart()));
	}
	
	public NodeVisitor getActionExecutor(AbstractModel m)
	{
		return new NodeActionExecutor(getContext(m.getDrawStartPosition(), m.getStartAngle()), m.getActions());
	}
	
	public Context getContext(PVector pos, float angle)
	{
		return new Context(this, drawables, new PVector(scale * width * pos.x, scale * height * pos.y), angle);
	}
}
